package com.pattern.behavioural;

import ch.qos.logback.classic.servlet.LogbackServletContextListener;

import java.awt.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Observable;

/**
 * @author Ping
 * @date 2022/4/25 14:31
 **/
public class ObserverDemo {
    public static void main(String args[]) {
        Observable obs ;
        LogbackServletContextListener lister ;

        TeacherSubj teacherSubj = new TeacherSubj() ;
        EmotionalListener listener = new StuListener() ;
        EmotionalListener listener1 = new StuListener() ;
        /*
        build relations
         */
        teacherSubj.addListener(listener);
        teacherSubj.addListener(listener1);
        /**
         * trigger
         */
        teacherSubj.changeHappy();

    }


}

/**
 * Event
 */
class EmotionalEvent {
    String content ;

    public EmotionalEvent(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}

/**
 * Abstract Observer
 */
interface EmotionalListener {
    public void reactionOn(EmotionalEvent event) ;

}

/**
 * Subject:
 * one to many for subject and observers.
 */
class TeacherSubj {
    /**
     * many listeners.
     */
    private List<EmotionalListener> listeners = new ArrayList<>() ;
    public void addListener(EmotionalListener listener) {
        this.listeners.add(listener) ;
    }
    public void changeHappy() {
        EmotionalEvent happyEvent = new EmotionalEvent("teacher was happy" ) ;
        /*
        notify all listeners the happy event
         */
        for (EmotionalListener listener : this.listeners) {
            listener.reactionOn(happyEvent);
        }

    }
}

/**
 * Concrete Observer/Listener
 */
class StuListener implements EmotionalListener {
    @Override
    public void reactionOn(EmotionalEvent event) {
        System.out.println("Students do reacton on teacher's emotional event since "
                + event.getContent()) ;
    }
}

class CryEvent {
    String catType ;
    Date time ;
    int volume ;

    public CryEvent(String catType, int volume) {
        this.catType = catType;
        this.time = new Date();
        this.volume = volume;
    }
}

class Cat {
    List<CryListener> listeners = new ArrayList<>() ;

    public void cry() {
        System.out.println("the cat was crying.") ;
        /**
         * generate a cry event
         */
        CryEvent cryEvent = new CryEvent("CAT_TYPE", 5) ;
        /*
        Notify all listeners
         */
        this.listeners.stream().forEach(lis -> lis.response(cryEvent)) ;
    }

}
interface CryListener {
    public void response(CryEvent cryEvent) ;
}

class Dog implements  CryListener{
    @Override
    public void response(CryEvent cryEvent) {
    // do real reaction
    }
}
class Mouse implements CryListener {
    @Override
    public void response(CryEvent cryEvent) {
// do real reaction.
    }
}


